<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>2_复习</title>
  </head>
  <body>
    <script type="text/javascript">
      // 对象中存在的属性描述符有两种主要类型：数据描述符和访问器描述符。
      // 数据描述符是一个具有可写或不可写值的属性。访问器描述符是由 getter/setter 函数对描述的属性。
      // 描述符只能是这两种类型之一，不能同时为两者。
      // 数据描述符和访问器描述符都是对象。
      // 它们共享以下可选键（请注意：在使用 Object.defineProperty() 定义属性的情况下，下述所有键都是默认值）：
      // configurable: 属性是否可以被修改，不能删除，其他描述符属性也被控制 默认值： false
      // enumerable: 是否在对应对象属性枚举中出现 默认值： false
      // value: 与属性相关联的值 默认值： undefined
      // writable: 与属性相关联的值是否可以使用赋值运算符是否更改 默认值：false

      // 访问器属性还可以是：
      // get 属性的 getter 的函数 默认值：undefined
      // set 属性的 setter 的函数 默认值：undefined

      // 如果描述符没有 value、writable、get 和 set 键中的任何一个，它将被视为数据描述符。如果描述符同时具有 [value 或 writable] 和 [get 或 set] 键，则会抛出异常。

      // 直接在一个对象上定义一个新属性，或修改其现有属性，并返回此对象。

      const object1 = {};
      // // 1. 使用 null 原型，没有继承的属性
      // const descriptor = Object.create(null);
      // descriptor.value = "static";

      // // 默认情况下：它们是不可枚举、不可配置、不可写
      // Object.defineProperty(object1, "key", descriptor);


      // 重复利用同一对象;
      function withValue(value) {
        const d =
          withValue.d ||
          (withValue.d = {
            enumerable: false,
            writable: false,
            configurable: false,
            value,
          });

        // 避免重复赋值
        if (d.value !== value) d.value = value;

        return d;
      }
      // 然后
      Object.defineProperty(object1, "key", withValue("static"));


      console.log(object1); // Expected output: 42
    </script>
  </body>
</html>
